use salvo::prelude::*;
use serde::Serialize;
use std::error::Error as StdError;
use thiserror::Error;

// 错误码常量定义
pub mod codes {
    // 成功代码
    pub const SUCCESS: &str = "0000";

    // 业务错误码 (1xxx)
    pub const VALIDATION_ERROR: &str = "1001";
    pub const BUSINESS_LOGIC_ERROR: &str = "1002";
    pub const PERMISSION_DENIED: &str = "1003";
    pub const RESOURCE_NOT_FOUND: &str = "1004";
    pub const RESOURCE_ALREADY_EXISTS: &str = "1005";
    pub const OPERATION_NOT_ALLOWED: &str = "1006";

    // 系统错误码 (2xxx)
    pub const DATABASE_ERROR: &str = "2001";
    pub const CACHE_ERROR: &str = "2002";
    pub const NETWORK_ERROR: &str = "2003";
    pub const FILE_SYSTEM_ERROR: &str = "2004";
    pub const CONFIGURATION_ERROR: &str = "2005";

    // 外部服务错误码 (3xxx)
    pub const EXTERNAL_SERVICE_ERROR: &str = "3001";
    pub const EXTERNAL_API_ERROR: &str = "3002";
    pub const THIRD_PARTY_SERVICE_ERROR: &str = "3003";

    // RPC/gRPC 错误码 (4xxx)
    pub const RPC_ERROR: &str = "4001";
    pub const GRPC_ERROR: &str = "4002";
    pub const RPC_UNAVAILABLE: &str = "4003";
    pub const RPC_TIMEOUT: &str = "4004";
    pub const RPC_CANCELLED: &str = "4005";

    // 系统内部错误码 (5xxx)
    pub const INTERNAL_SERVER_ERROR: &str = "5001";
    pub const SERVICE_UNAVAILABLE: &str = "5002";
    pub const TIMEOUT_ERROR: &str = "5003";
    pub const UNKNOWN_ERROR: &str = "5999";
}

// 错误位置信息结构体
#[derive(Debug, Clone, Serialize)]
pub struct ErrorLocation {
    pub file: String,
    pub line: u32,
    pub column: u32,
}

impl ErrorLocation {
    #[track_caller]
    pub fn capture() -> Self {
        let location = std::panic::Location::caller();
        Self {
            file: location.file().to_string(),
            line: location.line(),
            column: location.column(),
        }
    }

    pub fn format(&self) -> String {
        format!("{}:{}:{}", self.file, self.line, self.column)
    }
}

// 统一响应结构体
#[derive(Serialize, Debug, ToSchema)]
pub struct ApiResponse<T> {
    pub code: String,
    pub message: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub data: Option<T>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub details: Option<ErrorDetails>,
}

// 错误详情结构体
#[derive(Serialize, Debug, ToSchema)]
pub struct ErrorDetails {
    pub location: String,
    pub timestamp: String,
    pub request_id: Option<String>,
    pub http_status: u16,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub source_chain: Option<Vec<String>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub stack_trace: Option<String>,
}

// 定义应用级别的错误类型
#[derive(Error, Debug)]
pub enum AppError {
    #[error("数据库错误: {message}")]
    Database {
        message: String,
        location: ErrorLocation,
        #[source]
        source: Option<Box<dyn std::error::Error + Send + Sync>>,
    },

    #[error("验证失败: {message}")]
    Validation {
        message: String,
        location: ErrorLocation,
        #[source]
        source: Option<Box<dyn std::error::Error + Send + Sync>>,
    },

    #[error("权限不足")]
    Unauthorized {
        location: ErrorLocation,
        #[source]
        source: Option<Box<dyn std::error::Error + Send + Sync>>,
    },

    #[error("资源未找到: {message}")]
    NotFound {
        message: String,
        location: ErrorLocation,
        #[source]
        source: Option<Box<dyn std::error::Error + Send + Sync>>,
    },

    #[error("内部服务器错误: {message}")]
    Internal {
        message: String,
        location: ErrorLocation,
        #[source]
        source: Option<Box<dyn std::error::Error + Send + Sync>>,
    },

    #[error("外部服务错误: {message}")]
    ExternalService {
        message: String,
        location: ErrorLocation,
        #[source]
        source: Option<Box<dyn std::error::Error + Send + Sync>>,
    },

    #[error("业务逻辑错误: {message}")]
    Business {
        message: String,
        location: ErrorLocation,
        #[source]
        source: Option<Box<dyn std::error::Error + Send + Sync>>,
    },

    #[error("配置错误: {message}")]
    Configuration {
        message: String,
        location: ErrorLocation,
        #[source]
        source: Option<Box<dyn std::error::Error + Send + Sync>>,
    },

    #[error("网络错误: {message}")]
    Network {
        message: String,
        location: ErrorLocation,
        #[source]
        source: Option<Box<dyn std::error::Error + Send + Sync>>,
    },

    #[error("超时错误: {message}")]
    Timeout {
        message: String,
        location: ErrorLocation,
        #[source]
        source: Option<Box<dyn std::error::Error + Send + Sync>>,
    },

    #[error("RPC调用错误: {message}")]
    Rpc {
        message: String,
        location: ErrorLocation,
        #[source]
        source: Option<Box<dyn std::error::Error + Send + Sync>>,
    },

    #[error("gRPC错误: {message}")]
    Grpc {
        message: String,
        location: ErrorLocation,
        grpc_code: tonic::Code,
        #[source]
        source: Option<Box<dyn std::error::Error + Send + Sync>>,
    },
}

impl AppError {
    // 错误创建方法，自动捕捉调用位置
    #[track_caller]
    pub fn validation(message: &str) -> Self {
        let location = ErrorLocation::capture();

        tracing::error!(
            error_type = "ValidationError",
            message = message,
            location = %location.format(),
            "验证错误"
        );

        Self::Validation {
            message: message.to_string(),
            location,
            source: None,
        }
    }

    #[track_caller]
    pub fn validation_with_source<E>(message: &str, source: E) -> Self
    where
        E: std::error::Error + Send + Sync + 'static,
    {
        let location = ErrorLocation::capture();

        tracing::error!(
            error_type = "ValidationError",
            message = message,
            source = %source,
            location = %location.format(),
            "验证错误(带源错误)"
        );

        Self::Validation {
            message: message.to_string(),
            location,
            source: Some(Box::new(source)),
        }
    }

    #[track_caller]
    pub fn business(message: &str) -> Self {
        let location = ErrorLocation::capture();

        tracing::error!(
            error_type = "BusinessError",
            message = message,
            location = %location.format(),
            "业务逻辑错误"
        );

        Self::Business {
            message: message.to_string(),
            location,
            source: None,
        }
    }

    #[track_caller]
    pub fn business_with_source<E>(message: &str, source: E) -> Self
    where
        E: std::error::Error + Send + Sync + 'static,
    {
        let location = ErrorLocation::capture();

        tracing::error!(
            error_type = "BusinessError",
            message = message,
            source = %source,
            location = %location.format(),
            "业务逻辑错误(带源错误)"
        );

        Self::Business {
            message: message.to_string(),
            location,
            source: Some(Box::new(source)),
        }
    }

    #[track_caller]
    pub fn not_found(resource: &str) -> Self {
        let location = ErrorLocation::capture();

        tracing::warn!(
            error_type = "NotFoundError",
            resource = resource,
            location = %location.format(),
            "资源未找到"
        );

        Self::NotFound {
            message: resource.to_string(),
            location,
            source: None,
        }
    }

    #[track_caller]
    pub fn not_found_with_source<E>(resource: &str, source: E) -> Self
    where
        E: std::error::Error + Send + Sync + 'static,
    {
        let location = ErrorLocation::capture();

        tracing::warn!(
            error_type = "NotFoundError",
            resource = resource,
            source = %source,
            location = %location.format(),
            "资源未找到(带源错误)"
        );

        Self::NotFound {
            message: resource.to_string(),
            location,
            source: Some(Box::new(source)),
        }
    }

    #[track_caller]
    pub fn internal(message: &str) -> Self {
        let location = ErrorLocation::capture();

        tracing::error!(
            error_type = "InternalError",
            message = message,
            location = %location.format(),
            "内部错误"
        );

        Self::Internal {
            message: message.to_string(),
            location,
            source: None,
        }
    }

    #[track_caller]
    pub fn internal_with_source<E>(message: &str, source: E) -> Self
    where
        E: std::error::Error + Send + Sync + 'static,
    {
        let location = ErrorLocation::capture();

        tracing::error!(
            error_type = "InternalError",
            message = message,
            source = %source,
            location = %location.format(),
            "内部错误(带源错误)"
        );

        Self::Internal {
            message: message.to_string(),
            location,
            source: Some(Box::new(source)),
        }
    }

    #[track_caller]
    pub fn database(message: &str) -> Self {
        let location = ErrorLocation::capture();

        tracing::error!(
            error_type = "DatabaseError",
            message = message,
            location = %location.format(),
            "数据库错误"
        );

        Self::Database {
            message: message.to_string(),
            location,
            source: None,
        }
    }

    #[track_caller]
    pub fn database_with_source<E>(message: &str, source: E) -> Self
    where
        E: std::error::Error + Send + Sync + 'static,
    {
        let location = ErrorLocation::capture();

        tracing::error!(
            error_type = "DatabaseError",
            message = message,
            source = %source,
            location = %location.format(),
            "数据库错误(带源错误)"
        );

        Self::Database {
            message: message.to_string(),
            location,
            source: Some(Box::new(source)),
        }
    }

    #[track_caller]
    pub fn external_service(message: &str) -> Self {
        let location = ErrorLocation::capture();

        tracing::error!(
            error_type = "ExternalServiceError",
            message = message,
            location = %location.format(),
            "外部服务错误"
        );

        Self::ExternalService {
            message: message.to_string(),
            location,
            source: None,
        }
    }

    #[track_caller]
    pub fn external_service_with_source<E>(message: &str, source: E) -> Self
    where
        E: std::error::Error + Send + Sync + 'static,
    {
        let location = ErrorLocation::capture();

        tracing::error!(
            error_type = "ExternalServiceError",
            message = message,
            source = %source,
            location = %location.format(),
            "外部服务错误(带源错误)"
        );

        Self::ExternalService {
            message: message.to_string(),
            location,
            source: Some(Box::new(source)),
        }
    }

    #[track_caller]
    pub fn network(message: &str) -> Self {
        let location = ErrorLocation::capture();

        tracing::error!(
            error_type = "NetworkError",
            message = message,
            location = %location.format(),
            "网络错误"
        );

        Self::Network {
            message: message.to_string(),
            location,
            source: None,
        }
    }

    #[track_caller]
    pub fn network_with_source<E>(message: &str, source: E) -> Self
    where
        E: std::error::Error + Send + Sync + 'static,
    {
        let location = ErrorLocation::capture();

        tracing::error!(
            error_type = "NetworkError",
            message = message,
            source = %source,
            location = %location.format(),
            "网络错误(带源错误)"
        );

        Self::Network {
            message: message.to_string(),
            location,
            source: Some(Box::new(source)),
        }
    }

    #[track_caller]
    pub fn timeout(message: &str) -> Self {
        let location = ErrorLocation::capture();

        tracing::error!(
            error_type = "TimeoutError",
            message = message,
            location = %location.format(),
            "超时错误"
        );

        Self::Timeout {
            message: message.to_string(),
            location,
            source: None,
        }
    }

    #[track_caller]
    pub fn timeout_with_source<E>(message: &str, source: E) -> Self
    where
        E: std::error::Error + Send + Sync + 'static,
    {
        let location = ErrorLocation::capture();

        tracing::error!(
            error_type = "TimeoutError",
            message = message,
            source = %source,
            location = %location.format(),
            "超时错误(带源错误)"
        );

        Self::Timeout {
            message: message.to_string(),
            location,
            source: Some(Box::new(source)),
        }
    }

    #[track_caller]
    pub fn configuration(message: &str) -> Self {
        let location = ErrorLocation::capture();

        tracing::error!(
            error_type = "ConfigurationError",
            message = message,
            location = %location.format(),
            "配置错误"
        );

        Self::Configuration {
            message: message.to_string(),
            location,
            source: None,
        }
    }

    #[track_caller]
    pub fn configuration_with_source<E>(message: &str, source: E) -> Self
    where
        E: std::error::Error + Send + Sync + 'static,
    {
        let location = ErrorLocation::capture();

        tracing::error!(
            error_type = "ConfigurationError",
            message = message,
            source = %source,
            location = %location.format(),
            "配置错误(带源错误)"
        );

        Self::Configuration {
            message: message.to_string(),
            location,
            source: Some(Box::new(source)),
        }
    }

    #[track_caller]
    pub fn unauthorized() -> Self {
        let location = ErrorLocation::capture();

        tracing::warn!(
            error_type = "UnauthorizedError",
            location = %location.format(),
            "未授权访问"
        );

        Self::Unauthorized {
            location,
            source: None,
        }
    }

    #[track_caller]
    pub fn unauthorized_with_source<E>(source: E) -> Self
    where
        E: std::error::Error + Send + Sync + 'static,
    {
        let location = ErrorLocation::capture();

        tracing::warn!(
            error_type = "UnauthorizedError",
            source = %source,
            location = %location.format(),
            "未授权访问(带源错误)"
        );

        Self::Unauthorized {
            location,
            source: Some(Box::new(source)),
        }
    }

    #[track_caller]
    pub fn rpc(message: &str) -> Self {
        let location = ErrorLocation::capture();

        tracing::error!(
            error_type = "RpcError",
            message = message,
            location = %location.format(),
            "RPC调用错误"
        );

        Self::Rpc {
            message: message.to_string(),
            location,
            source: None,
        }
    }

    #[track_caller]
    pub fn rpc_with_source<E>(message: &str, source: E) -> Self
    where
        E: std::error::Error + Send + Sync + 'static,
    {
        let location = ErrorLocation::capture();

        tracing::error!(
            error_type = "RpcError",
            message = message,
            source = %source,
            location = %location.format(),
            "RPC调用错误(带源错误)"
        );

        Self::Rpc {
            message: message.to_string(),
            location,
            source: Some(Box::new(source)),
        }
    }

    #[track_caller]
    pub fn grpc(message: &str, grpc_code: tonic::Code) -> Self {
        let location = ErrorLocation::capture();

        tracing::error!(
            error_type = "GrpcError",
            message = message,
            grpc_code = ?grpc_code,
            location = %location.format(),
            "gRPC错误"
        );

        Self::Grpc {
            message: message.to_string(),
            location,
            grpc_code,
            source: None,
        }
    }

    #[track_caller]
    pub fn grpc_with_source<E>(message: &str, grpc_code: tonic::Code, source: E) -> Self
    where
        E: std::error::Error + Send + Sync + 'static,
    {
        let location = ErrorLocation::capture();

        tracing::error!(
            error_type = "GrpcError",
            message = message,
            grpc_code = ?grpc_code,
            source = %source,
            location = %location.format(),
            "gRPC错误(带源错误)"
        );

        Self::Grpc {
            message: message.to_string(),
            location,
            grpc_code,
            source: Some(Box::new(source)),
        }
    }

    // 从任意错误转换的通用方法
    #[track_caller]
    pub fn from_error<E>(error_type: &str, message: &str, source: E) -> Self
    where
        E: std::error::Error + Send + Sync + 'static,
    {
        let location = ErrorLocation::capture();

        tracing::error!(
            error_type = error_type,
            message = message,
            source = %source,
            location = %location.format(),
            "从源错误转换"
        );

        match error_type {
            "validation" => Self::Validation {
                message: message.to_string(),
                location,
                source: Some(Box::new(source)),
            },
            "business" => Self::Business {
                message: message.to_string(),
                location,
                source: Some(Box::new(source)),
            },
            "database" => Self::Database {
                message: message.to_string(),
                location,
                source: Some(Box::new(source)),
            },
            "internal" => Self::Internal {
                message: message.to_string(),
                location,
                source: Some(Box::new(source)),
            },
            "not_found" => Self::NotFound {
                message: message.to_string(),
                location,
                source: Some(Box::new(source)),
            },
            "external_service" => Self::ExternalService {
                message: message.to_string(),
                location,
                source: Some(Box::new(source)),
            },
            "network" => Self::Network {
                message: message.to_string(),
                location,
                source: Some(Box::new(source)),
            },
            "timeout" => Self::Timeout {
                message: message.to_string(),
                location,
                source: Some(Box::new(source)),
            },
            "configuration" => Self::Configuration {
                message: message.to_string(),
                location,
                source: Some(Box::new(source)),
            },
            "rpc" => Self::Rpc {
                message: message.to_string(),
                location,
                source: Some(Box::new(source)),
            },
            _ => Self::Internal {
                message: format!("{}: {}", error_type, message),
                location,
                source: Some(Box::new(source)),
            },
        }
    }

    // 从 tonic::Status 转换错误的便捷方法
    #[track_caller]
    pub fn from_tonic_status(status: tonic::Status) -> Self {
        let location = ErrorLocation::capture();
        let grpc_code = status.code();

        let (message, error_type) = match grpc_code {
            tonic::Code::NotFound => (format!("资源未找到: {}", status.message()), "NotFoundError"),
            tonic::Code::InvalidArgument => (
                format!("请求参数无效: {}", status.message()),
                "ValidationError",
            ),
            tonic::Code::Unauthenticated => (
                format!("认证失败: {}", status.message()),
                "UnauthorizedError",
            ),
            tonic::Code::PermissionDenied => (
                format!("权限不足: {}", status.message()),
                "UnauthorizedError",
            ),
            tonic::Code::Unavailable => (
                format!("服务不可用: {}", status.message()),
                "ExternalServiceError",
            ),
            tonic::Code::DeadlineExceeded => {
                (format!("请求超时: {}", status.message()), "TimeoutError")
            }
            tonic::Code::Cancelled => (format!("请求已取消: {}", status.message()), "RpcError"),
            _ => (format!("gRPC调用失败: {}", status.message()), "GrpcError"),
        };

        tracing::error!(
            error_type = error_type,
            message = %message,
            grpc_code = ?grpc_code,
            grpc_message = %status.message(),
            location = %location.format(),
            "从tonic::Status转换错误"
        );

        match grpc_code {
            tonic::Code::NotFound => Self::NotFound {
                message: status.message().to_string(),
                location,
                source: Some(Box::new(status)),
            },
            tonic::Code::InvalidArgument => Self::Validation {
                message: status.message().to_string(),
                location,
                source: Some(Box::new(status)),
            },
            tonic::Code::Unauthenticated | tonic::Code::PermissionDenied => Self::Unauthorized {
                location,
                source: Some(Box::new(status)),
            },
            tonic::Code::Unavailable => Self::ExternalService {
                message: status.message().to_string(),
                location,
                source: Some(Box::new(status)),
            },
            tonic::Code::DeadlineExceeded => Self::Timeout {
                message: status.message().to_string(),
                location,
                source: Some(Box::new(status)),
            },
            tonic::Code::Cancelled => Self::Rpc {
                message: status.message().to_string(),
                location,
                source: Some(Box::new(status)),
            },
            _ => Self::Grpc {
                message: status.message().to_string(),
                location,
                grpc_code,
                source: Some(Box::new(status)),
            },
        }
    }

    // 获取错误位置
    pub fn location(&self) -> &ErrorLocation {
        match self {
            AppError::Database { location, .. } => location,
            AppError::Validation { location, .. } => location,
            AppError::Unauthorized { location, .. } => location,
            AppError::NotFound { location, .. } => location,
            AppError::Internal { location, .. } => location,
            AppError::ExternalService { location, .. } => location,
            AppError::Business { location, .. } => location,
            AppError::Configuration { location, .. } => location,
            AppError::Network { location, .. } => location,
            AppError::Timeout { location, .. } => location,
            AppError::Rpc { location, .. } => location,
            AppError::Grpc { location, .. } => location,
        }
    }

    // 根据错误类型获取HTTP状态码
    pub fn status_code(&self) -> StatusCode {
        match self {
            AppError::Database { .. } => StatusCode::INTERNAL_SERVER_ERROR,
            AppError::Validation { .. } => StatusCode::BAD_REQUEST,
            AppError::Unauthorized { .. } => StatusCode::UNAUTHORIZED,
            AppError::NotFound { .. } => StatusCode::NOT_FOUND,
            AppError::Internal { .. } => StatusCode::INTERNAL_SERVER_ERROR,
            AppError::ExternalService { .. } => StatusCode::BAD_GATEWAY,
            AppError::Business { .. } => StatusCode::BAD_REQUEST,
            AppError::Configuration { .. } => StatusCode::INTERNAL_SERVER_ERROR,
            AppError::Network { .. } => StatusCode::BAD_GATEWAY,
            AppError::Timeout { .. } => StatusCode::REQUEST_TIMEOUT,
            AppError::Rpc { .. } => StatusCode::BAD_GATEWAY,
            AppError::Grpc { .. } => StatusCode::BAD_GATEWAY,
        }
    }

    // 获取错误码
    pub fn error_code(&self) -> &'static str {
        match self {
            AppError::Database { .. } => codes::DATABASE_ERROR,
            AppError::Validation { .. } => codes::VALIDATION_ERROR,
            AppError::Unauthorized { .. } => codes::PERMISSION_DENIED,
            AppError::NotFound { .. } => codes::RESOURCE_NOT_FOUND,
            AppError::Internal { .. } => codes::INTERNAL_SERVER_ERROR,
            AppError::ExternalService { .. } => codes::EXTERNAL_SERVICE_ERROR,
            AppError::Business { .. } => codes::BUSINESS_LOGIC_ERROR,
            AppError::Configuration { .. } => codes::CONFIGURATION_ERROR,
            AppError::Network { .. } => codes::NETWORK_ERROR,
            AppError::Timeout { .. } => codes::TIMEOUT_ERROR,
            AppError::Rpc { .. } => codes::RPC_ERROR,
            AppError::Grpc { .. } => codes::GRPC_ERROR,
        }
    }

    // 获取错误类型字符串
    pub fn error_type(&self) -> &'static str {
        match self {
            AppError::Database { .. } => "DatabaseError",
            AppError::Validation { .. } => "ValidationError",
            AppError::Unauthorized { .. } => "UnauthorizedError",
            AppError::NotFound { .. } => "NotFoundError",
            AppError::Internal { .. } => "InternalError",
            AppError::ExternalService { .. } => "ExternalServiceError",
            AppError::Business { .. } => "BusinessError",
            AppError::Configuration { .. } => "ConfigurationError",
            AppError::Network { .. } => "NetworkError",
            AppError::Timeout { .. } => "TimeoutError",
            AppError::Rpc { .. } => "RpcError",
            AppError::Grpc { .. } => "GrpcError",
        }
    }

    // 检查是否应该显示详细信息
    fn should_show_details(&self, _req: &Request, _depot: &Depot) -> bool {
        std::env::var("APP_ENV")
            .unwrap_or_else(|_| "production".to_string())
            .to_lowercase()
            == "development"
    }

    // 构建错误源链
    fn build_source_chain(&self) -> Vec<String> {
        let mut chain = Vec::new();
        let mut current_source = self.source();

        while let Some(source) = current_source {
            chain.push(source.to_string());
            current_source = source.source();
        }

        chain
    }

    // 获取堆栈跟踪
    fn get_stack_trace(&self) -> Option<String> {
        if std::env::var("APP_ENV")
            .unwrap_or_else(|_| "production".to_string())
            .to_lowercase()
            == "development"
        {
            Some(format!("{:?}", self))
        } else {
            None
        }
    }

    // 构建错误响应
    fn to_error_response(&self, req: &Request, depot: &Depot) -> ApiResponse<()> {
        let show_details = self.should_show_details(req, depot);

        ApiResponse {
            code: self.error_code().to_string(),
            message: if show_details {
                self.to_string()
            } else {
                // 生产环境下的用户友好消息
                match self {
                    AppError::Database { .. } => "数据库服务暂时不可用，请稍后重试".to_string(),
                    AppError::Internal { .. } => "系统内部错误，请联系管理员".to_string(),
                    AppError::ExternalService { .. } => "外部服务异常，请稍后重试".to_string(),
                    AppError::Network { .. } => "网络连接异常，请检查网络设置".to_string(),
                    AppError::Timeout { .. } => "请求超时，请稍后重试".to_string(),
                    AppError::Configuration { .. } => "系统配置异常，请联系管理员".to_string(),
                    AppError::Rpc { .. } => "服务调用异常，请稍后重试".to_string(),
                    AppError::Grpc { .. } => "服务调用异常，请稍后重试".to_string(),
                    _ => self.to_string(), // 对于用户错误，显示原始消息
                }
            },
            data: None,
            details: if show_details {
                let source_chain = self.build_source_chain();
                Some(ErrorDetails {
                    location: self.location().format(),
                    timestamp: chrono::Utc::now().to_rfc3339(),
                    request_id: req
                        .headers()
                        .get("x-request-id")
                        .and_then(|v| v.to_str().ok())
                        .map(|s| s.to_string()),
                    http_status: self.status_code().as_u16(),
                    source_chain: if source_chain.is_empty() {
                        None
                    } else {
                        Some(source_chain)
                    },
                    stack_trace: self.get_stack_trace(),
                })
            } else {
                None
            },
        }
    }
}

// 为AppError实现Writer trait，使其能够作为Salvo的响应
#[async_trait::async_trait]
impl Writer for AppError {
    async fn write(mut self, _req: &mut Request, _depot: &mut Depot, res: &mut Response) {
        let error_response = self.to_error_response(_req, _depot);

        res.status_code(self.status_code());
        res.render(Json(error_response));
    }
}

// 定义应用级别的Result类型
pub type AppResult<T> = Result<T, AppError>;

/// 标准的端点返回类型（用于OpenAPI）
pub type EndpointResult<T> = Result<ApiResponse<T>, AppError>;

/// Salvo端点返回类型（简化版）
pub type SalvoResult<T> = Result<Json<ApiResponse<T>>, StatusError>;

/// 创建成功的Salvo响应
pub fn salvo_success<T>(data: T) -> SalvoResult<T>
where
    T: Serialize,
{
    Ok(Json(ApiResponse::success(data)))
}

/// 创建带消息的成功Salvo响应
pub fn salvo_success_with_message<T>(data: T, message: &str) -> SalvoResult<T>
where
    T: Serialize,
{
    Ok(Json(ApiResponse::success_with_message(data, message)))
}

// 便捷函数：创建成功的 endpoint 响应
pub fn endpoint_success<T>(data: T) -> EndpointResult<T>
where
    T: Serialize,
{
    Ok(ApiResponse::success(data))
}

// 便捷函数：创建带消息的成功 endpoint 响应
pub fn endpoint_success_with_message<T>(data: T, message: &str) -> EndpointResult<T>
where
    T: Serialize,
{
    Ok(ApiResponse::success_with_message(data, message))
}

// 便捷宏：简化 endpoint 成功响应创建
#[macro_export]
macro_rules! endpoint_success {
    ($data:expr) => {
        utils::response::endpoint_success($data)
    };
    ($data:expr, $message:expr) => {
        utils::response::endpoint_success_with_message($data, $message)
    };
}

// ApiResponse的便捷构造方法
impl<T> ApiResponse<T> {
    /// 创建成功响应
    pub fn success(data: T) -> Self
    where
        T: Serialize,
    {
        Self {
            code: codes::SUCCESS.to_string(),
            message: "操作成功".to_string(),
            data: Some(data),
            details: None,
        }
    }

    /// 创建成功响应，带自定义消息
    pub fn success_with_message(data: T, message: &str) -> Self
    where
        T: Serialize,
    {
        Self {
            code: codes::SUCCESS.to_string(),
            message: message.to_string(),
            data: Some(data),
            details: None,
        }
    }

    /// 创建错误响应
    pub fn error(code: &str, message: &str) -> ApiResponse<()> {
        ApiResponse {
            code: code.to_string(),
            message: message.to_string(),
            data: None,
            details: None,
        }
    }

    /// 创建带详情的错误响应
    pub fn error_with_details(code: &str, message: &str, details: ErrorDetails) -> ApiResponse<()> {
        ApiResponse {
            code: code.to_string(),
            message: message.to_string(),
            data: None,
            details: Some(details),
        }
    }
}

// 为ApiResponse实现Writer trait，使其能够作为Salvo的响应
#[async_trait::async_trait]
impl<T> Writer for ApiResponse<T>
where
    T: Serialize + Send + Sync,
{
    async fn write(mut self, _req: &mut Request, _depot: &mut Depot, res: &mut Response) {
        res.render(Json(self));
    }
}

// 实现 EndpointOutRegister trait 以支持 OpenAPI 文档生成
#[cfg(feature = "oapi")]
impl<T> salvo::oapi::EndpointOutRegister for ApiResponse<T>
where
    T: salvo::oapi::ToSchema + Send + Sync,
{
    fn register(components: &mut salvo::oapi::Components, operation: &mut salvo::oapi::Operation) {
        // 创建 ApiResponse 的 schema
        let data_schema = T::to_schema(components);

        // 创建 ErrorDetails 的 schema
        let error_details_schema = salvo::oapi::Object::new()
            .property(
                "location",
                salvo::oapi::Object::new().schema_type(salvo::oapi::SchemaType::String),
            )
            .property(
                "timestamp",
                salvo::oapi::Object::new().schema_type(salvo::oapi::SchemaType::String),
            )
            .property(
                "request_id",
                salvo::oapi::Object::new().schema_type(salvo::oapi::SchemaType::String),
            )
            .property(
                "http_status",
                salvo::oapi::Object::new().schema_type(salvo::oapi::SchemaType::Integer),
            )
            .property(
                "source_chain",
                salvo::oapi::Object::new().schema_type(salvo::oapi::SchemaType::Array),
            )
            .property(
                "stack_trace",
                salvo::oapi::Object::new().schema_type(salvo::oapi::SchemaType::String),
            );

        // 创建完整的 ApiResponse schema
        let response_schema = salvo::oapi::Object::new()
            .property(
                "code",
                salvo::oapi::Object::new().schema_type(salvo::oapi::SchemaType::String),
            )
            .property(
                "message",
                salvo::oapi::Object::new().schema_type(salvo::oapi::SchemaType::String),
            )
            .property("data", data_schema)
            .property("details", error_details_schema);

        // 注册成功响应
        operation.responses.insert(
            "200",
            salvo::oapi::Response::new("Success").add_content("application/json", response_schema),
        );
    }
}

// 为 AppError 实现 EndpointOutRegister trait（简化版本）
impl salvo::oapi::EndpointOutRegister for AppError {
    fn register(_components: &mut salvo::oapi::Components, operation: &mut salvo::oapi::Operation) {
        // 简化的错误响应注册，只添加响应描述
        operation.responses.insert(
            "400",
            salvo::oapi::Response::new("Bad Request")
                .description("客户端请求错误，包括验证失败、业务逻辑错误等"),
        );
        operation.responses.insert(
            "401",
            salvo::oapi::Response::new("Unauthorized")
                .description("未授权访问，需要身份验证"),
        );
        operation.responses.insert(
            "403",
            salvo::oapi::Response::new("Forbidden")
                .description("权限不足，拒绝访问"),
        );
        operation.responses.insert(
            "404",
            salvo::oapi::Response::new("Not Found")
                .description("请求的资源未找到"),
        );
        operation.responses.insert(
            "500",
            salvo::oapi::Response::new("Internal Server Error")
                .description("服务器内部错误，包括数据库错误、配置错误等"),
        );
    }
}

// 便捷的错误创建宏
#[macro_export]
macro_rules! app_error {
    (validation, $msg:expr) => {
        AppError::validation($msg)
    };
    (validation, $msg:expr, $source:expr) => {
        AppError::validation_with_source($msg, $source)
    };
    (business, $msg:expr) => {
        AppError::business($msg)
    };
    (business, $msg:expr, $source:expr) => {
        AppError::business_with_source($msg, $source)
    };
    (not_found, $resource:expr) => {
        AppError::not_found($resource)
    };
    (not_found, $resource:expr, $source:expr) => {
        AppError::not_found_with_source($resource, $source)
    };
    (internal, $msg:expr) => {
        AppError::internal($msg)
    };
    (internal, $msg:expr, $source:expr) => {
        AppError::internal_with_source($msg, $source)
    };
    (database, $msg:expr) => {
        AppError::database($msg)
    };
    (database, $msg:expr, $source:expr) => {
        AppError::database_with_source($msg, $source)
    };
    (external_service, $msg:expr) => {
        AppError::external_service($msg)
    };
    (external_service, $msg:expr, $source:expr) => {
        AppError::external_service_with_source($msg, $source)
    };
    (network, $msg:expr) => {
        AppError::network($msg)
    };
    (network, $msg:expr, $source:expr) => {
        AppError::network_with_source($msg, $source)
    };
    (timeout, $msg:expr) => {
        AppError::timeout($msg)
    };
    (timeout, $msg:expr, $source:expr) => {
        AppError::timeout_with_source($msg, $source)
    };
    (configuration, $msg:expr) => {
        AppError::configuration($msg)
    };
    (configuration, $msg:expr, $source:expr) => {
        AppError::configuration_with_source($msg, $source)
    };
    (unauthorized) => {
        AppError::unauthorized()
    };
    (unauthorized, $source:expr) => {
        AppError::unauthorized_with_source($source)
    };
    (rpc, $msg:expr) => {
        AppError::rpc($msg)
    };
    (rpc, $msg:expr, $source:expr) => {
        AppError::rpc_with_source($msg, $source)
    };
    (grpc, $msg:expr, $code:expr) => {
        AppError::grpc($msg, $code)
    };
    (grpc, $msg:expr, $code:expr, $source:expr) => {
        AppError::grpc_with_source($msg, $code, $source)
    };
    (from_tonic, $status:expr) => {
        AppError::from_tonic_status($status)
    };
    (from, $error_type:expr, $msg:expr, $source:expr) => {
        AppError::from_error($error_type, $msg, $source)
    };
}

// 便捷的成功响应宏
#[macro_export]
macro_rules! success_response {
    ($data:expr) => {
        ApiResponse::success($data)
    };
    ($data:expr, $message:expr) => {
        ApiResponse::success_with_message($data, $message)
    };
}

// 便捷的错误响应宏
#[macro_export]
macro_rules! error_response {
    ($code:expr, $message:expr) => {
        ApiResponse::error($code, $message)
    };
}

// ===========================================
// 以下是演示用的Handler函数
// ===========================================

// Handler for English greeting - 演示验证错误
#[handler]
async fn hello() -> AppResult<ApiResponse<&'static str>> {
    Err(app_error!(validation, "用户输入验证失败"))
}

// Handler demonstrating not found error
#[handler]
async fn not_found_demo() -> AppResult<ApiResponse<&'static str>> {
    Err(app_error!(not_found, "用户ID: 12345"))
}

// Handler demonstrating internal error
#[handler]
async fn internal_error_demo() -> AppResult<ApiResponse<&'static str>> {
    Err(app_error!(internal, "配置文件解析失败"))
}

// Handler demonstrating database error
#[handler]
async fn database_error_demo() -> AppResult<ApiResponse<&'static str>> {
    Err(app_error!(database, "连接池已满"))
}

// Handler demonstrating business logic error
#[handler]
async fn business_error_demo() -> AppResult<ApiResponse<&'static str>> {
    Err(app_error!(business, "用户余额不足，无法完成交易"))
}

// Handler demonstrating network error
#[handler]
async fn network_error_demo() -> AppResult<ApiResponse<&'static str>> {
    Err(app_error!(network, "无法连接到支付网关"))
}

// Handler demonstrating external service error
#[handler]
async fn external_service_error_demo() -> AppResult<ApiResponse<&'static str>> {
    Err(app_error!(external_service, "短信服务提供商返回错误"))
}

// Handler demonstrating timeout error
#[handler]
async fn timeout_error_demo() -> AppResult<ApiResponse<&'static str>> {
    Err(app_error!(timeout, "数据库查询超时"))
}

// Handler demonstrating configuration error
#[handler]
async fn configuration_error_demo() -> AppResult<ApiResponse<&'static str>> {
    Err(app_error!(configuration, "Redis连接配置无效"))
}

// Handler demonstrating unauthorized error
#[handler]
async fn unauthorized_demo() -> AppResult<ApiResponse<&'static str>> {
    Err(app_error!(unauthorized))
}

// Handler demonstrating RPC error
#[handler]
async fn rpc_error_demo() -> AppResult<ApiResponse<&'static str>> {
    Err(app_error!(rpc, "RPC服务调用失败"))
}

// Handler demonstrating gRPC error
#[handler]
async fn grpc_error_demo() -> AppResult<ApiResponse<&'static str>> {
    Err(app_error!(grpc, "gRPC服务不可用", tonic::Code::Unavailable))
}

// Handler demonstrating tonic status conversion
#[handler]
async fn tonic_error_demo() -> AppResult<ApiResponse<&'static str>> {
    let status = tonic::Status::new(tonic::Code::InvalidArgument, "Invalid request parameters");
    Err(app_error!(from_tonic, status))
}

// Handler demonstrating generic error conversion
#[handler]
async fn generic_error_demo() -> AppResult<ApiResponse<&'static str>> {
    let custom_err = std::io::Error::new(std::io::ErrorKind::PermissionDenied, "Access denied");
    Err(app_error!(from, "permission", "权限验证失败", custom_err))
}

// Handler for successful response - 演示成功响应
#[handler]
async fn success() -> AppResult<ApiResponse<serde_json::Value>> {
    let data = serde_json::json!({
        "captcha_img": "",
        "uuid": "123456"
    });
    Ok(success_response!(data, "验证码生成成功"))
}

// Handler for successful response with different data
#[handler]
async fn success_user_info() -> AppResult<ApiResponse<serde_json::Value>> {
    let data = serde_json::json!({
        "user_id": 12345,
        "username": "张三",
        "email": "zhangsan@example.com"
    });
    Ok(success_response!(data))
}

// Handler for Chinese greeting
#[handler]
async fn hello_zh() -> AppResult<ApiResponse<&'static str>> {
    Ok(success_response!("你好，世界！", "中文问候"))
}
